package com.css.zfzx.sjcj.modules.qhcriteriaqueries.service.impl;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.css.bpm.platform.components.attach.service.SysAttachment;
import com.css.bpm.platform.components.attach.viewobjects.SysAttachmentVO;
import com.css.bpm.platform.utils.PlatformPageUtils;
import com.css.bpm.platform.utils.UUIDGenerator;
import com.css.zfzx.sjcj.common.utils.EasyPoiExcelUtil;
import com.css.zfzx.sjcj.common.utils.ServerUtil;
import com.css.zfzx.sjcj.common.utils.ZipUtils;
import com.css.zfzx.sjcj.modules.qhcriteriaqueries.service.QhCriteriaQueriesService;
import com.css.zfzx.sjcj.modules.qhdrillhistogram.repository.QhDrillHistogramRepository;
import com.css.zfzx.sjcj.modules.qhdrillhistogram.repository.entity.QhDrillHistogramEntity;
import com.css.zfzx.sjcj.modules.qhdrillhistogram.service.QhDrillHistogramService;
import com.css.zfzx.sjcj.modules.qhdrillhistogram.viewobjects.QhDrillHistogramVO;
import com.css.zfzx.sjcj.modules.qhdrilloverview.repository.QhDrillOverviewNativeRepository;
import com.css.zfzx.sjcj.modules.qhdrilloverview.repository.QhDrillOverviewRepository;
import com.css.zfzx.sjcj.modules.qhdrilloverview.repository.entity.QhDrillOverviewEntity;
import com.css.zfzx.sjcj.modules.qhdrilloverview.service.QhDrillOverviewService;
import com.css.zfzx.sjcj.modules.qhdrilloverview.viewobjects.QhDrillOverviewQueryParams;
import com.css.zfzx.sjcj.modules.qhdrilloverview.viewobjects.QhDrillOverviewVO;
import com.css.zfzx.sjcj.modules.qhseismicfortification.repository.QhSeismicFortificationRepository;
import com.css.zfzx.sjcj.modules.qhseismicfortification.repository.entity.QhSeismicFortificationEntity;
import com.css.zfzx.sjcj.modules.qhseismicfortification.service.QhSeismicFortificationService;
import com.css.zfzx.sjcj.modules.qhseismicfortification.viewobjects.QhSeismicFortificationVO;
import com.css.zfzx.sjcj.modules.qhsitushearwave.repository.QhSituShearWaveRepository;
import com.css.zfzx.sjcj.modules.qhsitushearwave.repository.entity.QhSituShearWaveEntity;
import com.css.zfzx.sjcj.modules.qhsitushearwave.service.QhSituShearWaveService;
import com.css.zfzx.sjcj.modules.qhsitushearwave.viewobjects.QhSituShearWaveVO;
import com.css.zfzx.sjcj.modules.qhsoildynamic.repository.QhSoilDynamicRepository;
import com.css.zfzx.sjcj.modules.qhsoildynamic.repository.entity.QhSoilDynamicEntity;
import com.css.zfzx.sjcj.modules.qhsoildynamic.service.QhSoilDynamicService;
import com.css.zfzx.sjcj.modules.qhsoildynamic.viewobjects.QhSoilDynamicVO;
import com.css.zfzx.sjcj.modules.qhstandardpenetration.repository.QhStandardPenetrationRepository;
import com.css.zfzx.sjcj.modules.qhstandardpenetration.repository.entity.QhStandardPenetrationEntity;
import com.css.zfzx.sjcj.modules.qhstandardpenetration.service.QhStandardPenetrationService;
import com.css.zfzx.sjcj.modules.qhstandardpenetration.viewobjects.QhStandardPenetrationVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author tao
 * @date 2020-11-14
 */
@Slf4j
@Service
public class QhCriteriaQueriesServiceImpl implements QhCriteriaQueriesService {

    @Autowired
    private QhDrillOverviewNativeRepository qhDrillOverviewNativeRepository;
    @Autowired
    private QhDrillOverviewRepository qhDrillOverviewRepository;
    @Autowired
    private QhDrillHistogramRepository qhDrillHistogramRepository;
    @Autowired
    private QhStandardPenetrationRepository qhStandardPenetrationRepository;
    @Autowired
    private QhSituShearWaveRepository qhSituShearWaveRepository;
    @Autowired
    private QhSoilDynamicRepository qhSoilDynamicRepository;
    @Autowired
    private QhSeismicFortificationRepository qhSeismicFortificationRepository;

    @Autowired
    private QhDrillOverviewService qhDrillOverviewService;
    @Autowired
    private QhDrillHistogramService qhDrillHistogramService;
    @Autowired
    private QhStandardPenetrationService qhStandardPenetrationService;
    @Autowired
    private QhSituShearWaveService qhSituShearWaveService;
    @Autowired
    private QhSoilDynamicService qhSoilDynamicService;
    @Autowired
    private QhSeismicFortificationService qhSeismicFortificationService;

    //附件操作
    @Autowired
    private SysAttachment sysAttachment;

    @Override
    public JSONObject queryCriteria(QhDrillOverviewQueryParams queryParams, int curPage, int pageSize) {
        JSONObject resJsonObject = new JSONObject();

        //查询钻井概况
        Page<QhDrillOverviewEntity> qhDrillOverviewPage = this.qhDrillOverviewNativeRepository.queryQhDrillOverviews(queryParams, curPage, pageSize);
        if(qhDrillOverviewPage.getTotalElements() < 1) {
            return resJsonObject;
        }
        JSONObject drillOverview = PlatformPageUtils.formatPageData(qhDrillOverviewPage);
        resJsonObject.put("drillOverview", drillOverview);

        //构建其它表查询信息
        List<String> drillCodeList = new ArrayList<>();
        for(QhDrillOverviewEntity qhDrillOverview : qhDrillOverviewPage.getContent()) {
            String drillCode = qhDrillOverview.getDrillCode();
            drillCodeList.add(drillCode);
        }

        String isValid = "1";

        //查询综合柱状图
        List<QhDrillHistogramEntity> qhDrillHistogramList = this.qhDrillHistogramRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        Object drillHistogram = JSON.toJSON(qhDrillHistogramList);
        resJsonObject.put("drillHistogram", drillHistogram);

        //查询钻孔标准贯入原位测试结果
        List<QhStandardPenetrationEntity> qhStandardPenetrationList = this.qhStandardPenetrationRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        Object standardPenetration = JSON.toJSON(qhStandardPenetrationList);
        resJsonObject.put("standardPenetration", standardPenetration);

        //查询钻孔原位剪切波速测试结果
        List<QhSituShearWaveEntity> qhSituShearWaveList = qhSituShearWaveRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        Object situShearWave = JSON.toJSON(qhSituShearWaveList);
        resJsonObject.put("situShearWave", situShearWave);

        //查询土动力测试数据
        List<QhSoilDynamicEntity> qhSoilDynamicList = qhSoilDynamicRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        Object soilDynamic = JSON.toJSON(qhSoilDynamicList);
        resJsonObject.put("soilDynamic", soilDynamic);

        //查询抗震设防参数
        List<QhSeismicFortificationEntity> qhSeismicFortificationList = qhSeismicFortificationRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        Object seismicFortification = JSON.toJSON(qhSeismicFortificationList);
        resJsonObject.put("seismicFortification",seismicFortification);

        return resJsonObject;
    }

    @Override
    public String exportExcel(QhDrillOverviewQueryParams queryParams, HttpServletResponse response) {
        try{
            //查询钻井概况
            List<QhDrillOverviewEntity> qhDrillOverviewList = qhDrillOverviewNativeRepository.listQhDrillOverviews(queryParams);
            if(qhDrillOverviewList.size() < 1) {
                return "无要导出的数据";
            }

            exportExcel(qhDrillOverviewList,response);

            return "导出成功";
        } catch (Exception e) {
            return "导出失败";
        }
    }

    @Override
    public String exportExcel(String ids, HttpServletResponse response) {
        try{
            //查询钻井概况
            List<String> idList = Arrays.asList(ids.split(","));
            List<QhDrillOverviewEntity> qhDrillOverviewList = this.qhDrillOverviewRepository.findAllById(idList);
            if(qhDrillOverviewList.size() < 1) {
                return "无要导出的数据";
            }

            exportExcel(qhDrillOverviewList,response);

            return "导出成功";
        } catch (Exception e) {
            log.error(e.getMessage());
            return "导出失败";
        }
    }

    private void addExcelInZip(List<?> data, Class<?> pojoClass, String name, ZipOutputStream zipOS) throws IOException {
        try {
            String titleName = name + "统计";
            String fileName = name + ".xls";
            ExportParams exportParams = new ExportParams(titleName, name);
            Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, data);
            if (workbook != null) {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                workbook.write(outputStream);
                InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
                ZipUtils.doZip(inputStream, zipOS, fileName);
            }
        } catch(IOException e) {
            log.error(e.getMessage());
            throw e;
        }
    }

    @Override
    public String importExcel(MultipartFile[] files) {
        try {
            // 返回的消息
            StringBuilder returnMsg = new StringBuilder();
            // 附件列表<文件名称，附件Id>
            Map<String,String> pictureMap = new HashMap<>();
            // 数据文件列表
            List<MultipartFile> xlsFiles = new ArrayList<>();

            //循环处理每一个文件
            for(MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
                if(isPictureFile(fileName)) {
                    String attachId = UUIDGenerator.getUUID();
                    String truck = "1";
                    SysAttachmentVO vo = new SysAttachmentVO();
                    vo.setAttachMd5("1");
                    vo.setAttachId(attachId);
                    vo.setFileDirId("defaultDirectory");
                    HashMap chunkInfo = new HashMap();
                    chunkInfo.put("chunk", truck);
                    chunkInfo.put("chunkSize", "1");
                    chunkInfo.put("attachId", attachId);
                    vo.setChunkInfo(chunkInfo);
                    vo.setAttachChunk(new Integer(truck));
                    SysAttachmentVO newVo = sysAttachment.writeFile(file,vo);
                    sysAttachment.saveFile(newVo);
                    pictureMap.put(fileName,attachId);
                } else {
                    xlsFiles.add(file);
                }
            }

            //循环处理每一个数据文件
            for(MultipartFile file : xlsFiles) {
                String fileName = file.getOriginalFilename().trim();
                if(fileName.contains("抗震设防参数")) {
                    String msg = qhSeismicFortificationService.importExcel(file);
                    returnMsg.append("抗震设防参数表\n");
                    returnMsg.append(msg);
                } else if(fileName.contains("土动力测试数据")) {
                    String msg = qhSoilDynamicService.importExcel(file);
                    returnMsg.append("土动力测试数据表\n");
                    returnMsg.append(msg);
                } else if(fileName.contains("钻孔标准贯入原位测试结果")) {
                    String msg = qhStandardPenetrationService.importExcel(file);
                    returnMsg.append("钻孔标准贯入原位测试结果表\n");
                    returnMsg.append(msg);
                } else if(fileName.contains("钻孔概况")) {
                    String msg = qhDrillOverviewService.importExcel(file);
                    returnMsg.append("钻孔概况表\n");
                    returnMsg.append(msg);
                } else if(fileName.contains("钻孔原位剪切波速测试结果")) {
                    String msg = qhSituShearWaveService.importExcel(file);
                    returnMsg.append("钻孔原位剪切波速测试结果表\n");
                    returnMsg.append(msg);
                } else if(fileName.contains("钻孔综合柱状图")) {
                    String msg = qhDrillHistogramService.importExcel(file,pictureMap);
                    returnMsg.append("钻孔综合柱状图表\n");
                    returnMsg.append(msg);
                }
            }

            if(returnMsg.toString().length() < 10) {
                returnMsg.append("导入的文件格式不正确");
            }
            return returnMsg.toString();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "导入失败，请检查数据正确性";
        }
    }

    private boolean isPictureFile(String fileName) {
        if (fileName != null && "".equals(fileName.trim())) { return false; }

        String ext = fileName.substring(fileName.lastIndexOf('.') + 1);
        String uExt = ext.toUpperCase();

        return uExt.equals("PNG") || uExt.equals("JPG") || uExt.equals("GIF") || uExt.equals("JPEG");
    }

    private void exportExcel(List<QhDrillOverviewEntity> qhDrillOverviewList, HttpServletResponse response) throws IOException{
        //构建其它表查询信息
        List<String> drillCodeList = new ArrayList<>();
        List<String> drillOverviewIds = new ArrayList<>();
        for(QhDrillOverviewEntity qhDrillOverview : qhDrillOverviewList) {
            String drillCode = qhDrillOverview.getDrillCode();
            String id = qhDrillOverview.getId();
            drillCodeList.add(drillCode);
            drillOverviewIds.add(id);
        }
        String isValid = "1";

        //设置返回信息
        String zipFileName = "区划数据.zip";
        //zipFileName = new String(zipFileName.getBytes("UTF-8"), "ISO-8859-1");
        //response.setContentType("multipart/form-data");//1.设置文件ContentType类型，这样设置，会自动判断下载文件类型
        response.setHeader("content-Type", "application/zip");
        response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(zipFileName, "UTF-8"));
        response.setCharacterEncoding("UTF-8");
        ZipOutputStream zipStream=new ZipOutputStream(response.getOutputStream());

        //导出钻井概况
        ArrayList<QhDrillOverviewVO> vosDO = new ArrayList<>();
        for (QhDrillOverviewEntity areaEntity : qhDrillOverviewList) {
            QhDrillOverviewVO vo = new QhDrillOverviewVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosDO.add(vo);
        }
        addExcelInZip(vosDO,QhDrillOverviewVO.class,"钻孔概况",zipStream);

        //查询综合柱状图
        List<QhDrillHistogramEntity> qhDrillHistogramList = this.qhDrillHistogramRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        ArrayList<QhDrillHistogramVO> vosDH = new ArrayList<>();
        for (QhDrillHistogramEntity areaEntity : qhDrillHistogramList) {
            QhDrillHistogramVO vo = new QhDrillHistogramVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosDH.add(vo);
        }
        addExcelInZip(vosDH,QhDrillHistogramVO.class,"钻孔综合柱状图",zipStream);

        //查询钻孔标准贯入原位测试结果
        List<QhStandardPenetrationEntity> qhStandardPenetrationList = this.qhStandardPenetrationRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        ArrayList<QhStandardPenetrationVO> vosSP = new ArrayList<>();
        for (QhStandardPenetrationEntity areaEntity : qhStandardPenetrationList) {
            QhStandardPenetrationVO vo = new QhStandardPenetrationVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosSP.add(vo);
        }
        addExcelInZip(vosSP,QhStandardPenetrationVO.class,"钻孔标准贯入原位测试结果",zipStream);

        //查询钻孔原位剪切波速测试结果
        List<QhSituShearWaveEntity> qhSituShearWaveList = qhSituShearWaveRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        ArrayList<QhSituShearWaveVO> vosSW = new ArrayList<>();
        for (QhSituShearWaveEntity areaEntity : qhSituShearWaveList) {
            QhSituShearWaveVO vo = new QhSituShearWaveVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosSW.add(vo);
        }
        addExcelInZip(vosSW,QhSituShearWaveVO.class,"钻孔原位剪切波速测试结果",zipStream);

        //查询土动力测试数据
        List<QhSoilDynamicEntity> qhSoilDynamicList = qhSoilDynamicRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        ArrayList<QhSoilDynamicVO> vosSD = new ArrayList<>();
        for (QhSoilDynamicEntity areaEntity : qhSoilDynamicList) {
            QhSoilDynamicVO vo = new QhSoilDynamicVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosSD.add(vo);
        }
        addExcelInZip(vosSD,QhSoilDynamicVO.class,"土动力测试数据",zipStream);

        //查询抗震设防参数
        List<QhSeismicFortificationEntity> qhSeismicFortificationList = qhSeismicFortificationRepository.findByIsValidAndDrillCodeIn(isValid,drillCodeList);
        ArrayList<QhSeismicFortificationVO> vosSF = new ArrayList<>();
        for (QhSeismicFortificationEntity areaEntity : qhSeismicFortificationList) {
            QhSeismicFortificationVO vo = new QhSeismicFortificationVO();
            BeanUtils.copyProperties(areaEntity, vo);
            vosSF.add(vo);
        }
        addExcelInZip(vosSF,QhSeismicFortificationVO.class,"抗震设防参数",zipStream);

        zipStream.close();
    }

    /**
     *  判断当前用户是否是终极质检员
     *
     * @return 是否终检员 0:否 1:是
     */
    @Override
    public String isUltimateQc(){
        return ServerUtil.isUltimateQc() ? "1" : "0";
    }
}
